package Or

import "C"
import (
	"encoding/json"
	"errors"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"strconv"
	"strings"
)

func (or TableInfoMeta) IfTablePartitionSum(s global.TablesMetaInfoInput) (partitionData global.PartitionSumReturnResult, err error) {
	var (
		event = "[oracleIfTablePartitionSum]"
		res   any
	)
	strSql := fmt.Sprintf(" SELECT * FROM (SELECT PARTITIONING_TYPE || ',' || SUBPARTITIONING_TYPE AS \"partitionType\" FROM ALL_PART_TABLES WHERE OWNER='%v' AND TABLE_NAME='%v') A, (SELECT SUM(DECODE(COMPOSITE,'YES',SUBPARTITION_COUNT,1)) AS \"sum\" FROM all_tab_partitions WHERE TABLE_OWNER='%v' AND TABLE_NAME = '%v') B", s.TableInfo.Schema, s.TableInfo.Table, s.TableInfo.Schema, s.TableInfo.Table)
	if _, res, err = ExecSelectSql(ExecSqlInputS{
		Ss:           s,
		Event:        event,
		SelectSqlStr: strSql,
		Expect:       ETL.Map,
	}); err != nil || res == nil {
		if err != nil {
			err = errors.New(fmt.Sprintf("%v %v", event, err))
		}
		return
	}
	if v1, ok := res.(map[string]any)["partitionType"]; ok {
		partitionData.Type = fmt.Sprintf("%v", v1)
	}
	if v1, ok := res.(map[string]any)["sum"]; ok {
		if len(fmt.Sprintf("%v", v1)) > 0 {
			if v2, err1 := strconv.ParseInt(fmt.Sprintf("%v", v1), 10, 64); err1 != nil {
				err = errors.New(fmt.Sprintf("%v table %v.%v partition sum conversion int failed. data is %v, error is %v", event, s.TableInfo.Schema, s.TableInfo.Table, res, err))
				return partitionData, err
			} else {
				partitionData.Sum = v2
			}
		}
	}
	if len(partitionData.Type) > 0 && partitionData.Sum > 0 {
		return partitionData, nil
	}
	return
}

func (or TableInfoMeta) partColumnActive(columnName []string, columnMeta []global.TableMeta) global.PartColumnMeta {
	var pc global.PartColumnMeta
	for _, v := range columnName {
		for _, p := range columnMeta {
			if strings.EqualFold(v, p.ColumnName) {
				pc.Type = append(pc.Type, p.ConvertColumnType.Type)
				pc.CharSet = append(pc.CharSet, p.Charset)
				pc.Collation = append(pc.Collation, p.CollationName)
			}
		}
	}
	return pc
}

func Distribution(s global.TablesMetaInfoInput) (res []global.GetTableDistributed, err error) {
	res = append(res, global.GetTableDistributed{
		Schema:             s.TableInfo.Schema,
		Table:              s.TableInfo.Table,
		DistributeMode:     "NORMAL",
		ShardName:          "single",
		FirstPartitionName: "single",
		BackendTableName:   s.TableInfo.Table,
	})
	return
}

func getDistribution(s global.TablesMetaInfoInput) (res []global.PartShardS, err error) {
	res = append(res, global.PartShardS{
		PartName:         "single",
		Mode:             "NORMAL",
		ShardName:        "single",
		BackendTableName: s.TableInfo.Table,
	})
	return
}

func (or TableInfoMeta) partitionBaseMetaActive(s global.TablesMetaInfoInput) (p partitionBaseMeta, err error) {
	var (
		event     = "[oraclePartitionConfig]"
		f1        any
		allResult global.AllReturnResult
		tc        TableColumn
	)
	//获取表的列信息
	if f1, err = tc.All(global.GetColumnTypeInput{
		LogSeq: s.LogSeq,
		DB:     s.DB,
		TableInfo: global.TableInfo{
			Schema: s.TableInfo.Schema,
			Table:  s.TableInfo.Table,
		},
	}); err != nil || f1 == nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain partitionBaseMeta information. error is:%v", event, err))
		return
	} else {
		p.columnMeta = allResult.Result
	}
	//获取表的分区信息
	if f1, err = or.GetPartitionMeta(s); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain partitionBaseMeta information. error is:%v", event, err))
		return
	}
	if f1 != nil && len(f1.([]global.GetPartitionMeta)) > 0 {
		p.partitionMeta = f1.([]global.GetPartitionMeta)
	}
	//获取表分布信息
	if f1, err = Distribution(s); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain partitionBaseMeta information. error is:%v", event, err))
		return
	}
	if f1 != nil && len(f1.([]global.GetTableDistributed)) > 0 {
		p.tableDistributed = f1.([]global.GetTableDistributed)
	}
	return
}

// FirstSubPartNameMarge 合并first Sub partition name
func (or TableInfoMeta) FirstSubPartNameMarge(s global.TablesMetaInfoInput) (q any, err error) {
	var (
		partitionShardMap   = make(map[string]global.BackendTable)
		PartMeth            string
		PartColumn          global.ManyLevelPartColumn
		partitionNameGarth  []string
		FirstNameMapSubName = make(map[string][]string)
		p                   partitionBaseMeta
	)
	if p, err = or.partitionBaseMetaActive(s); err != nil {
		return
	}
	for _, j := range p.tableDistributed {
		var key = j.FirstPartitionName
		if len(j.SubPartitionName) > 0 && j.SubPartitionName != "NULL" && j.SubPartitionName != "''" {
			key = fmt.Sprintf("%v#%v", key, j.SubPartitionName)
		}
		if strings.EqualFold(j.DistributeMode, "NORMAL") {
			key = "single"
		}
		partitionShardMap[key] = global.BackendTable{
			FirstPartitionName: j.FirstPartitionName,
			SubPartitionName:   j.SubPartitionName,
			ShardName:          j.ShardName,
			BackendTableName:   j.BackendTableName,
		}
	}
	//normal表
	if len(p.partitionMeta) == 0 {
		return global.FirstSubPartNameMargeData{
			PartMeth:              "single",
			FirstNameMapSubName:   FirstNameMapSubName,
			PartColumn:            PartColumn,
			PartitionNameGarth:    []string{"single"},
			PartitionBackendShard: partitionShardMap,
		}, nil
	}
	for _, v := range p.partitionMeta {
		//分区方法
		if len(PartMeth) == 0 {
			//分区方法合并
			PartMeth = v.FirstPartMeth
			if len(v.SubPartMeth) > 0 && v.SubPartMeth != "NULL" && v.SubPartMeth != "''" {
				PartMeth = fmt.Sprintf("%v_%v", PartMeth, v.SubPartMeth)
			}
			//分区列信息
			PartColumn.FirstPar = or.partColumnActive(v.FirstPartColumn, p.columnMeta)
			if len(v.SubPartColumn) > 0 {
				PartColumn.SubPar = or.partColumnActive(v.SubPartColumn, p.columnMeta)
			}
		}
		//分区名合并
		var key = v.FirstPartName
		if len(v.SubPartName) > 0 && v.SubPartName != "NULL" && v.SubPartName != "''" {
			key = fmt.Sprintf("%v#%v", key, v.SubPartName)
		}
		partitionNameGarth = append(partitionNameGarth, key)
		if _, ok := FirstNameMapSubName[v.FirstPartName]; !ok {
			if len(v.SubPartName) > 0 {
				FirstNameMapSubName[v.FirstPartName] = []string{v.SubPartName}
			} else {
				FirstNameMapSubName[v.FirstPartName] = []string{}
			}
		} else {
			if len(v.SubPartName) > 0 && v.SubPartName != "NULL" && v.SubPartName != "''" {
				FirstNameMapSubName[v.FirstPartName] = append(FirstNameMapSubName[v.FirstPartName], v.SubPartName)
			}
		}
	}
	return global.FirstSubPartNameMargeData{
		PartMeth:              PartMeth,
		FirstNameMapSubName:   FirstNameMapSubName,
		PartColumn:            PartColumn,
		PartitionNameGarth:    partitionNameGarth,
		PartitionBackendShard: partitionShardMap,
	}, nil
}

//disPartRules 处理每个分区的分区规则
/*
	处理如下：
	1：拆分分区规则中是否用到分区函数
	2：合并分区规则中多个值现象（主要是list集合）
	传参：每个分区数据
	返值：分区规则
*/
func (or TableInfoMeta) disPartRules(meth string, s any) (r string) {
	switch meth {
	case "RANGE":
		p := fmt.Sprintf("%v", s)
		if strings.Contains(strings.ToUpper(p), "HH24:MI:SS") {
			if n := strings.Index(p, "HH24:MI:SS"); n != -1 {
				p = p[:n]
			}
		}
		if strings.Contains(strings.ToUpper(p), "YY-MM-DD") {
			if n := strings.Index(p, "YY-MM-DD"); n != -1 {
				p = p[:n]
			}
		}
		if strings.Contains(strings.ToUpper(p), "(") {
			if n := strings.Index(p, "("); n != -1 {
				p = p[n+1:]
			}
		}
		if strings.Contains(strings.ToUpper(p), ",") {
			p = strings.Split(p, ",")[0]
		}
		if strings.Contains(p, "'") {
			p = fmt.Sprintf("'%v'", strings.TrimSpace(strings.ReplaceAll(p, "'", "")))
		}
		r = p
	case "LIST":
		l := fmt.Sprintf("%v", s)
		if len(l) == 0 {
			r = fmt.Sprintf("%v", s)
			return
		}
		if strings.Contains(l, ",") {
			var p []string
			for _, v := range strings.Split(l, ",") {
				p = append(p, strings.TrimSpace(v))
			}
			r = strings.Join(p, ",")
		}
	default:
		r = fmt.Sprintf("%v", s)
	}
	return
}

func getFirstPartColumn(s global.TablesMetaInfoInput) (result []string, err error) {
	var (
		f1    any
		event = "[GetFirstPartName]"
	)
	strSql := fmt.Sprintf("SELECT C.COLUMN_NAME AS \"partColumn\" \n"+
		"FROM ALL_PART_KEY_COLUMNS C \n"+
		"WHERE C.OWNER = '%v' AND C.NAME = '%v'",
		s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], StopTime: s.Input.SqlExecStopTime, SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.SMap); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain index information. error is:%v", event, err))
		return nil, err
	}
	if f1 == nil {
		return
	}
	for _, v := range f1.([]map[string]any) {
		if g, ok := v["partColumn"]; ok {
			result = append(result, fmt.Sprintf("%v", g))
		}
	}
	return
}
func getSubPartColumn(s global.TablesMetaInfoInput) (result []string, err error) {
	var (
		f1    any
		event = "[getSubPartColumn]"
	)
	strSql := fmt.Sprintf("SELECT C.COLUMN_NAME AS \"partColumn\" \n"+
		"FROM ALL_SUBPART_KEY_COLUMNS C \n"+
		"WHERE C.OWNER = '%v' AND C.NAME = '%v'",
		s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], StopTime: s.Input.SqlExecStopTime, SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.SMap); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain index information. error is:%v", event, err))
		return nil, err
	}
	if f1 == nil {
		return
	}
	for _, v := range f1.([]map[string]any) {
		if g, ok := v["partColumn"]; ok {
			result = append(result, fmt.Sprintf("%v", g))
		}
	}
	return
}
func getPartMeth(s global.TablesMetaInfoInput) (result []string, err error) {
	var (
		f1    any
		event = "[getSubPartColumn]"
	)
	strSql := fmt.Sprintf("SELECT C.PARTITIONING_TYPE AS \"firstPartMeth\",C.SUBPARTITIONING_TYPE AS \"subPartMeth\"  \n"+
		"FROM ALL_PART_TABLES C \n"+
		"WHERE C.OWNER = '%v' AND C.TABLE_NAME = '%v'",
		s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], StopTime: s.Input.SqlExecStopTime, SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.Map); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain index information. error is:%v", event, err))
		return nil, err
	}
	if f1 == nil {
		return
	}
	for _, v := range []string{"firstPartMeth", "subPartMeth"} {
		if g, ok := f1.(map[string]any)[v]; ok {
			result = append(result, fmt.Sprintf("%v", g))
		} else {
			result = append(result, fmt.Sprintf("none"))
		}
	}
	return
}
func getFirstPartName(s global.TablesMetaInfoInput) (result []global.PartitionNameRulesS, err error) {
	var (
		f1    any
		event = "[getSubPartColumn]"
	)
	strSql := fmt.Sprintf("SELECT C.PARTITION_NAME AS \"PartName\",C.SUBPARTITION_COUNT AS \"subSum\",C.PARTITION_POSITION AS \"Seq\",C.HIGH_VALUE AS \"Rules\" \n"+
		"FROM ALL_TAB_PARTITIONS C \n"+
		"WHERE C.TABLE_OWNER = '%v' AND C.TABLE_NAME = '%v' order by C.PARTITION_POSITION ",
		s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], StopTime: s.Input.SqlExecStopTime, SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.SMap); err != nil || f1 == nil {
		if err != nil {
			err = errors.New(fmt.Sprintf("%v sql exec fail. error is:%v", event, err))
		}
		return
	}
	for _, v := range f1.([]map[string]any) {
		var first global.PartitionNameRulesS
		if err = global.MapSubToStructSubJsonName(mapNullActive(v), &first); err != nil {
			return
		}
		result = append(result, first)
	}
	return
}

func getSubPartName(s global.TablesMetaInfoInput) (result map[string][]global.PartitionNameRulesS, err error) {
	var (
		f1    any
		event = "[getSubPartColumn]"
	)
	result = make(map[string][]global.PartitionNameRulesS)
	strSql := fmt.Sprintf("SELECT C.PARTITION_NAME AS \"firstPartName\",C.SUBPARTITION_NAME AS \"PartName\",C.SUBPARTITION_POSITION AS \"Seq\",C.HIGH_VALUE AS \"Rules\" \n"+
		"FROM ALL_TAB_SUBPARTITIONS C \n"+
		"WHERE C.TABLE_OWNER = '%v' AND C.TABLE_NAME = '%v' order by C.SUBPARTITION_POSITION ",
		s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], StopTime: s.Input.SqlExecStopTime, SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.SMap); err != nil || f1 == nil {
		if err != nil {
			err = errors.New(fmt.Sprintf("%v sql exec fail. error is:%v", event, err))
		}
		return
	}
	for _, v := range f1.([]map[string]any) {
		var firstName string
		if g, ok := v["firstPartName"]; ok {
			firstName = fmt.Sprintf("%v", g)
		}
		var sub global.PartitionNameRulesS
		if err = global.MapSubToStructSubJsonName(mapNullActive(v), &sub); err != nil {
			return nil, err
		}
		if g, ok := result[firstName]; ok {
			g = append(g, sub)
		} else {
			result[firstName] = []global.PartitionNameRulesS{sub}
		}
	}
	return
}
func colGetParameter(s global.TablesMetaInfoInput) global.GetColumnTypeInput {
	return global.GetColumnTypeInput{
		LogSeq: s.LogSeq,
		DB:     s.DB,
		TableInfo: global.TableInfo{
			SchemaTableGather: map[string]int{fmt.Sprintf("%v%v%v", s.TableInfo.Schema, global.SchemaTableSplit, s.TableInfo.Table): 1},
			Schema:            s.TableInfo.Schema,
			Table:             s.TableInfo.Table,
		},
	}
}
func partMetaBaseInit(s global.TablesMetaInfoInput) (res partMethBaseResultS, err error) {
	var (
		c TableColumn
	)
	if res.FirPartResult, err = getFirstPartName(s); err != nil {
		return
	}
	if res.SubPartResult, err = getSubPartName(s); err != nil {
		return
	}
	if res.MethResult, err = getPartMeth(s); err != nil {
		return
	}
	if res.FirPartColumnNameResult, err = getFirstPartColumn(s); err != nil {
		return
	}
	if res.SubPartColumnNameResult, err = getSubPartColumn(s); err != nil {
		return
	}
	if res.ColMetaResult, err = c.All(colGetParameter(s)); err != nil {
		return
	}
	return
}
func normalShardActive(p partMethBaseResultS) (res []global.PartShardS) {
	res = append(res, global.PartShardS{
		PartName:         "single",
		Mode:             "NORMAL",
		ShardName:        "single",
		BackendTableName: p.ColMetaResult.Result[0].TableName,
	})
	return
}

func partShardActive(p partMethBaseResultS) (res []global.PartShardS, partName []string) {
	resOld := normalShardActive(p)
	partName = []string{"single"}
	if len(p.FirPartResult) == 0 { //普通表
		res = resOld
		return
	}
	partName = []string{}
	for _, x := range p.FirPartResult {
		partName = append(partName, x.Name)
		res = append(res, global.PartShardS{
			Mode:             "NORMAL",
			PartName:         x.Name,
			ShardName:        "single",
			BackendTableName: resOld[0].BackendTableName,
		})
	}
	return
}

func partColumnActive(p partMethBaseResultS) (res global.PartDefinitionS) {
	if len(p.FirPartColumnNameResult) == 0 {
		return
	}
	for _, v := range p.ColMetaResult.Result {
		for _, x := range p.FirPartColumnNameResult {
			if strings.EqualFold(x, v.ColumnName) {
				res.PartColS.FirPartCol = append(res.PartColS.FirPartCol, v.ColumnName)
				res.PartColT.FirPartColType = append(res.PartColT.FirPartColType, v.ColumnType)
				res.PartColC.FirPartColChart = append(res.PartColC.FirPartColChart, v.Charset)
				res.PartColC.FirPartColCollation = append(res.PartColC.FirPartColCollation, v.CollationName)
			}
		}
		for _, x := range p.SubPartColumnNameResult {
			if strings.EqualFold(x, v.ColumnName) {
				res.PartColS.SubPartCol = append(res.PartColS.SubPartCol, v.ColumnName)
				res.PartColT.SubPartColType = append(res.PartColT.SubPartColType, v.ColumnType)
				res.PartColC.SubPartColChart = append(res.PartColC.SubPartColChart, v.Charset)
				res.PartColC.SubPartColCollation = append(res.PartColC.SubPartColCollation, v.CollationName)
			}
		}
	}
	return
}

func (or TableInfoMeta) GetPartMeta(s global.TablesMetaInfoInput) (res global.PartMetaResultS, err error) {
	var (
		baseResult partMethBaseResultS
	)
	if baseResult, err = partMetaBaseInit(s); err != nil {
		return
	}
	res.Shard, res.NameGarth = partShardActive(baseResult)
	res.Definition = partColumnActive(baseResult)
	if len(res.NameGarth) >= 1 {
		if !strings.EqualFold(res.NameGarth[0], "single") {
			res.Overview.Status = true
		}
	}
	return
}

func (or TableInfoMeta) GetPartitionMeta(s global.TablesMetaInfoInput) (any, error) {
	var (
		event = "[oracleGetPartitionMeta]"
		f1    any
		tpc   []global.GetPartitionMeta
		err   error
	)
	strSql := fmt.Sprintf("select A.TABLE_OWNER AS \"schema\",A.TABLE_NAME AS \"table\",A.PARTITION_NAME AS \"firstPartName\",B.SUBPARTITION_NAME AS \"subPartName\",A.PARTITION_POSITION AS \"firstPartSeq\",B.SUBPARTITION_POSITION AS \"subPartSeq\",Z.PARTITIONING_TYPE AS \"firstPartMeth\",Z.SUBPARTITIONING_TYPE AS \"subPartMeth\",E.\"firstPartColumn\", E.\"subPartColumn\", A.HIGH_VALUE AS \"partitionRules\" from ALL_TAB_PARTITIONS A LEFT join  ALL_TAB_SUBPARTITIONS B ON A.TABLE_OWNER = B.TABLE_OWNER AND A.TABLE_NAME = B.TABLE_NAME AND A.PARTITION_NAME = B.PARTITION_NAME LEFT JOIN ALL_PART_TABLES Z ON A.TABLE_OWNER = Z.OWNER AND A.TABLE_NAME = Z.TABLE_NAME LEFT JOIN (SELECT C.OWNER,C.NAME,C.COLUMN_NAME AS \"firstPartColumn\",D.COLUMN_NAME AS \"subPartColumn\" FROM ALL_PART_KEY_COLUMNS C LEFT JOIN ALL_SUBPART_KEY_COLUMNS D ON C.OWNER= D.OWNER AND C.NAME =D.NAME WHERE C.OWNER='%v' AND C.NAME='%v') E  ON A.TABLE_OWNER = E.OWNER AND A.TABLE_NAME = E.NAME WHERE A.table_owner = '%v' and A.table_NAME='%v' ORDER BY A.PARTITION_POSITION,B.SUBPARTITION_POSITION", s.TableInfo.Schema, s.TableInfo.Table, s.TableInfo.Schema, s.TableInfo.Table)
	active := ETL.InstanceActiveS{DBType: DBType, DB: s.DB["single"], SqlMode: true}
	if _, f1, err = active.SqlQuery(strSql, ETL.SMap); err != nil {
		err = errors.New(fmt.Sprintf("%v get Failed to obtain index information. error is:%v", event, err))
		return nil, err
	}
	if f1 == nil || len(f1.([]map[string]any)) == 0 {
		return nil, err
	}
	var partitionResult []map[string]any
	for _, v := range f1.([]map[string]any) {
		var p = make(map[string]any)
		for q, t := range v {
			switch fmt.Sprintf("%v", t) {
			case "<null>", "<entry>":
				p[q] = "NULL"
			default:
				p[q] = t
			}
		}
		partitionResult = append(partitionResult, p)
	}
	var columnFunc = map[string]string{"firstPartColumn": "firstPartColumnFunc", "subPartColumn": "subPartColumnFunc"}
	for _, v := range partitionResult {
		for k, w := range v { //处理无数据的自动显示为none的问题，变为空
			if strings.EqualFold(fmt.Sprintf("%v", w), "NONE") {
				v[k] = ""
			}
		}
		u := v
		//处理partition meth
		if w, ok := v["firstPartMeth"]; ok {
			meth := strings.ToUpper(fmt.Sprintf("%v", w))
			u["firstPartMeth"] = meth
		}
		//处理partition meth
		if w, ok := v["partitionRules"]; ok {
			u["partitionRules"] = or.disPartRules(u["firstPartMeth"].(string), w)
		}
		//处理first sub partition column and first sub partition func
		for _, z := range []string{"firstPartColumn", "subPartColumn"} {
			if w, ok := v[z]; ok {
				meth := strings.ToUpper(fmt.Sprintf("%v", w))
				var y, t []string
				for _, x := range strings.Split(strings.ReplaceAll(meth, "\"", ""), ",") {
					if strings.Contains(x, "(") && strings.Contains(x, ")") {
						var funcName, columnName string
						var left, right int
						if left = strings.Index(x, "("); left != -1 {
							funcName = x[:left]
						}
						if right = strings.Index(x, ")"); right != -1 {
							columnName = x[left+1 : right]
						}
						t = append(t, strings.TrimSpace(funcName))
						y = append(y, strings.TrimSpace(columnName))
					} else {
						y = append(y, strings.TrimSpace(x))
					}

				}
				u[z] = y
				u[columnFunc[z]] = t
			}
		}
		v1 := global.GetPartitionMeta{}
		// 将 map 转换为 JSON 字节流
		var jsonData []byte
		jsonData, err = json.Marshal(u)
		if err != nil {
			err = errors.New(fmt.Sprintf("%v []map[string]any strconv json fail. Execution process{strconv data:%v error:%v}", event, v, err))
			return nil, err
		}
		// 将 JSON 字节流反序列化为结构体
		err = json.Unmarshal(jsonData, &v1)
		if err != nil {
			err = errors.New(fmt.Sprintf("%v []byte json unmarshal struct fail. Execution process{strconv data:%v error:%v}", event, string(jsonData), err))
			return nil, err
		}
		tpc = append(tpc, v1)
	}
	return tpc, nil
}
func (or TableInfoMeta) PartitionConfig(s global.TablesMetaInfoInput) (any, error) {
	var (
		//Event               = "[PartitionConfig]"
		f1                  any
		tc                  TableColumn
		columnMeta          []global.TableMeta
		PartitionMeta       []global.GetPartitionMeta
		TableDistributed    []global.GetTableDistributed
		tpc                 []global.TablePartitionConfig
		firstPartitionMarge = make(map[string]int)
		firstPartitionGarth []global.SubPartitionMeta
		subPartitionMarge   = make(map[string][]global.SubPartitionMeta)
		err                 error
	)
	//获取表的列信息
	if f1, err = tc.All(colGetParameter(s)); err != nil || f1 == nil {
		return nil, err
	}
	columnMeta = f1.(global.AllReturnResult).Result
	//获取表的分区信息
	if f1, err = or.GetPartitionMeta(s); err != nil {
		return nil, err
	}
	if f1 != nil {
		PartitionMeta = f1.([]global.GetPartitionMeta)
	}
	//获取表分布信息
	f1, _ = Distribution(s)
	TableDistributed = f1.([]global.GetTableDistributed)
	var (
		getColumnType = func(x []string, o []global.TableMeta) (z []string) {
			for _, v := range o {
				for _, y := range x {
					if strings.EqualFold(v.ColumnName, y) {
						z = append(z, v.ColumnType)
					}
				}
			}
			return
		}
	)
	if len(PartitionMeta) == 0 {
		tpc = append(tpc, global.TablePartitionConfig{
			Schema:      s.TableInfo.Schema,
			Table:       s.TableInfo.Table,
			TableObject: "single",
			FirstPartition: global.SubPartitionMeta{
				Name: "single",
			},
			BackendTableName: s.TableInfo.Table,
			ShardName:        TableDistributed[0].ShardName,
		})
		return tpc, nil
	}
	for _, v := range PartitionMeta {
		var partRul = v.PartRul
		if strings.HasPrefix(partRul, "'TIMESTAMP") {
			partRul = strings.ReplaceAll(partRul, "TIMESTAMP ", "")
		}
		if _, ok := firstPartitionMarge[v.FirstPartName]; !ok {
			firstPartitionGarth = append(firstPartitionGarth, global.SubPartitionMeta{
				Sum:        strconv.Itoa(len(PartitionMeta)),
				Func:       v.FirstPartColumnFunc,
				Name:       v.FirstPartName,
				Meth:       v.FirstPartMeth,
				ColumnName: v.FirstPartColumn,
				ColumnType: getColumnType(v.FirstPartColumn, columnMeta),
				Rules:      partRul,
				Seq:        v.FirstPartSeq,
			})
			subPartitionMarge[v.FirstPartName] = []global.SubPartitionMeta{{
				Func:       v.SubPartColumnFunc,
				Name:       v.SubPartName,
				Meth:       v.SubPartMeth,
				ColumnName: v.SubPartColumn,
				ColumnType: getColumnType(v.SubPartColumn, columnMeta),
				Rules:      partRul,
				Seq:        v.SubPartSeq,
			}}
			firstPartitionMarge[v.FirstPartName]++
		} else {
			subPartitionMarge[v.FirstPartName] = append(subPartitionMarge[v.FirstPartName], global.SubPartitionMeta{
				Func:       v.SubPartColumnFunc,
				Name:       v.SubPartName,
				Meth:       v.SubPartMeth,
				ColumnName: v.SubPartColumn,
				ColumnType: getColumnType(v.SubPartColumn, columnMeta),
				Rules:      partRul,
				Seq:        v.SubPartSeq,
			})
		}
	}
	for _, v := range firstPartitionGarth {
		var subPartGarth []global.SubPartitionMeta
		var subPartMeth string
		if w, ok := subPartitionMarge[v.Name]; ok {
			subPartGarth = w
		}
		if len(subPartGarth) > 0 {
			subPartMeth = subPartGarth[0].Meth
		}
		tpc = append(tpc, global.TablePartitionConfig{
			Schema:           s.TableInfo.Schema,
			Table:            s.TableInfo.Table,
			FirstPartition:   v,
			SubPartMeth:      subPartMeth,
			SubPartMeta:      subPartGarth,
			ShardName:        "single",
			TableObject:      "partition",
			BackendTableName: s.TableInfo.Table,
		})
	}
	return tpc, nil
}

func (or TableInfoMeta) DropPartitionSql(_ global.TablesMetaInfoInput) (any, error) {
	return global.AlterSqlResult{}, nil
}
func (or TableInfoMeta) AddPartitionSql(_ global.TablesMetaInfoInput) (any, error) {
	return global.AlterSqlResult{}, nil
}
func (or TableInfoMeta) ModifyPartitionSql(_ global.TablesMetaInfoInput) (any, error) {
	return global.AlterSqlResult{}, nil
}
